﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Text;
using System.Threading.Tasks;

namespace Dubbo.Common.DynamicProxy
{
    public class ProxyGenerator
    {
        public static T CreateProxy<T>(IInvocationHandler handler)
        {
            return (T)new ClassProxy<T>(handler).GetTransparentProxy();
        }

        class ClassProxy<T> : RealProxy
        {
            private IInvocationHandler handler;

            public ClassProxy(IInvocationHandler handler)
                : base(typeof(T))
            {
                this.handler = handler;
            }

            public override IMessage Invoke(IMessage msg)
            {
                var methodCall = msg as IMethodCallMessage;
                var methodInfo = methodCall.MethodBase as MethodInfo;
                try
                {
                    var result = handler.Invoke(null, methodInfo, methodCall.InArgs);
                    return new ReturnMessage(result, null, 0,
                      methodCall.LogicalCallContext, methodCall);
                }
                catch (Exception e)
                {
                    return new ReturnMessage(e, methodCall);
                }
            }
        }
    }
}
